#include "jwt.h"
#include "utils.h"
#include "logger.h"

const char *my_secret_key = "Setekh-Secret-Key";

char *encodeJWT(char *aud)
{
    char *jwt;
    size_t jwt_length;

    struct l8w8jwt_encoding_params params;
    l8w8jwt_encoding_params_init(&params);

    params.alg = L8W8JWT_ALG_HS512;

    params.sub = "S1mple-NetDisk";
    params.sub_length = strlen("S1mple-NetDisk");

    params.iss = "Setekh";
    params.iss_length = strlen("Setekh");

    /*  params.aud = "User";
     params.aud_length = strlen("User"); */
    params.aud = aud;
    params.aud_length = strlen(aud);

    params.iat = l8w8jwt_time(NULL);
    params.exp = l8w8jwt_time(NULL) + 600; // Set to expire after 10 minutes (600 seconds).

    params.secret_key = (unsigned char *)my_secret_key;
    params.secret_key_length = strlen(my_secret_key);

    params.out = &jwt;
    params.out_length = &jwt_length;

    int r = l8w8jwt_encode(&params);
    LOG_DEBUG("JWT", "\nl8w8jwt_encode_hs512 function returned %s (code %d).\n\nCreated token: \n%s\n", r == L8W8JWT_SUCCESS ? "successfully" : "", r, jwt);

    char *jwt_str = (char *)malloc(jwt_length + 1);
    strcpy(jwt_str, jwt);

    l8w8jwt_free(jwt);
    return jwt_str;
}

int decodeJWT(const char *jwt, char *aud)
{
    struct l8w8jwt_decoding_params params;
    l8w8jwt_decoding_params_init(&params);

    params.alg = L8W8JWT_ALG_HS512;

    params.jwt = (char *)jwt;
    params.jwt_length = strlen(jwt);

    params.verification_key = (unsigned char *)my_secret_key;
    params.verification_key_length = strlen(my_secret_key);

    params.validate_iss = "Setekh";
    params.validate_iss_length = strlen(params.validate_iss);

    params.validate_sub = "S1mple-NetDisk";
    params.validate_sub_length = strlen(params.validate_sub);

    params.validate_exp = 1;
    params.exp_tolerance_seconds = 60;

    params.validate_iat = 1;
    params.iat_tolerance_seconds = 60;

    enum l8w8jwt_validation_result validation_result;
    struct l8w8jwt_claim *out_claims;
    size_t out_claims_length;
    int r = l8w8jwt_decode(&params, &validation_result, &out_claims, &out_claims_length);

    if (r == L8W8JWT_SUCCESS)
    {
        LOG_DEBUG("JWT", "l8w8jwt_decode function returned successfully (code %d).\n", r);
        LOG_DEBUG("JWT", "Validation result: %d\n", validation_result);

        for (size_t i = 0; i < out_claims_length; i++)
        {
            if (strcmp(out_claims[i].key, "aud") == 0)
            {
                LOG_DEBUG("JWT", "aud: %s\n", out_claims[i].value);
                strcpy(aud, out_claims[i].value);
            }
        }

        l8w8jwt_free_claims(out_claims, out_claims_length);
    }
    else
    {
        LOG_DEBUG("JWT", "l8w8jwt_decode function failed (code %d).\n", r);
        LOG_DEBUG("JWT", "Validation result: %d\n", validation_result);
    }

    return 0;
}